package com.perfma.xtest.boss;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.perfma.xtest.CollectionUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.util.*;

/**
 * @author: junhui.si
 * @date: 2020-11-28 15:25
 **/
public class Demo {
    static CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    static final String URL_LIST = "https://www.zhipin.com/wapi/zpboss/h5/boss/recommendGeekList";
    static final String URL_HELLO = "https://www.zhipin.com/wapi/zpboss/h5/chat/start?_=";
    static Set<String> expectSet;
    static LinkedHashMap<String, String> jodIdMap;
    static int failCount = 0;
    static int helloFailCount = 0;
    static long sleepTime = 450;

    static String logMsg = "序号: %s, 耗时: %s秒, 过滤已招呼人数:%s, 过滤工作不符人数:%s, 过滤年龄不符人数:%s, newFriend: %s.";
    static String endMsg = "总过滤人数:%s, 过滤已招呼人数:%s, 过滤工作不符人数:%s, 过滤年龄不符人数:%s ";
    static long time = 0L;
    static int no = 1;
    static Map<String, Integer> jobCountMap = Maps.newHashMap();
    static int totalFilterCount = 0;
    static int totalFilterCountOfJob = 0;
    static int totalFilterCountOfChat = 0;
    static int totalFilterCountOfAge = 0;
    static int totalFilterCountOfJobTemp = 0;
    static int totalFilterCountOfChatTemp = 0;
    static int totalFilterCountOfAgeTemp = 0;
    static int end = 0;

    // 活跃度。2501-刚刚活跃，2502-今日活跃
    static String active = "2502";

    static {
        expectSet = Sets.newHashSet();
        expectSet.add("送餐员");
        expectSet.add("快递员");
        expectSet.add("配送员");
        expectSet.add("货运司机");
        expectSet.add("配/理/拣/发货");
        expectSet.add("普工/操作工");
        expectSet.add("店员/营业员");
        expectSet.add("搬运工");
        expectSet.add("运输");
        expectSet.add("物流");
        expectSet.add("仓储");
        expectSet.add("拣货");
        expectSet.add("商务司机");
        expectSet.add("服务员");
        expectSet.add("学徒工");

        jodIdMap = Maps.newLinkedHashMap();
        jodIdMap.put("9a8d5cf00aa16bff1nVz2ti0FlVW", "春节多倍薪资急招普工");
        jodIdMap.put("c9248748fcbb68e61nVz3tu0FFtW", "春节三倍薪资+额外奖金急招配送");
        jodIdMap.put("a0612a5c404ff7111nVz3t2_F1NT", "春节多倍薪资急缺夜班搬货理货");
        jodIdMap.put("132c04211555a2171nZ629q8F1VY", "春节三倍薪资下沙急招7k分拣");
        jodIdMap.put("3a8349fb5b439f151nZ70t-7EFNU", "富阳夜班搬货理货员");
        jodIdMap.put("dffd7ffe233638821nRz3Nu1ElpW", "闲林配送员");
        jodIdMap.put("4037da74898bc74d1nR-3d67FVFR", "西湖文化广场配送员");
        jodIdMap.put("dd2a6ca107438dcc1nR62di7GFZT", "下沙配送员");
        jodIdMap.put("c659a66dcb8c43423nBy3N-9FlA~", "闲林配送员");
        jodIdMap.put("f2d259544af19a8c3nd909-6FlQ~", "仓前配送员");
        jodIdMap.put("7a218032dd04d44d3nZ92dy7ElM~", "留下配送员");
        jodIdMap.put("562baff5dae206ba3nZ92d28E1Q~", "崇贤配送员");
        jodIdMap.put("4fabdfc8974471fa33x93Nu8GFA~", "西湖大道配送员");
        jodIdMap.put("0ff03ae65d74eb7533x_3dW5GFA~", "滨江长河街道9k配送员");
        jodIdMap.put("d700551d05bd0dd233J939i0EFI~", "裕华大厦配送员");
        jodIdMap.put("bcece935e38d531633J83ti4F1A~", "复兴路万元配送员");
        jodIdMap.put("823fb944badf58fd33J53d20EFM~", "江干区新塘配送员");
        jodIdMap.put("cd47c368cd74dfe633J73ty6ElA~", "七堡配送员");
        jodIdMap.put("e66aba6380159aee33J62d-9GVo~", "四季广场配送员");
        jodIdMap.put("aef117ba7a29ad4d33F529y4EVY~", "拱墅区配送员");
        jodIdMap.put("6630ecf09f24e4b633F43Nq6EFQ~", "仓前配送员");
        jodIdMap.put("10ef6d6c0110f44a33F43Nm0FVQ~", "西湖区配送员");
        jodIdMap.put("deee786a966f40a233F73NS4EFs~", "萧山配送员");
        jodIdMap.put("d06ba2e639a97be833F72dS1F1E~", "叮咚凤起配送员");
        jodIdMap.put("f57b2ce77df0b17a33Bz3tq7GFE~", "转塘配送员");
        jodIdMap.put("fa03d2d9be7de21b33B53dq7EFY~", "留下配送员");
        jodIdMap.put("beb658d86aca524a33B53dm7ElY~", "五常配送员");
        jodIdMap.put("369e8d091cf95f6433B43tS4EFI~", "拱墅区大悦城配送员");
        jodIdMap.put("ed6150a535113a5a33B70tS4FFY~", "转塘配送员");
        jodIdMap.put("cdf025e8f3cec1d333B70tS8FVo~", "浦沿配送员");
        jodIdMap.put("33e1d4bbedfdcb3233B709y5EVQ~", "滨江配送员");
        jodIdMap.put("0c99d8b964067a7d33B70921EVc~", "余杭临平配送员");
        jodIdMap.put("8900822b0b7a906433B73t68F1s~", "下城区朝晖配送员");
        jodIdMap.put("6d02852f44e9353c33B62t-5EFo~", "临安配送员");
        jodIdMap.put("241c1ed44bfa64e433d93964Elo~", "江干区配送员");
        jodIdMap.put("6560d6e51e8364b833d92N6_FlA~", "江干景芳配送员");
        jodIdMap.put("d758dfb545b18c9c33d92t2_E1I~", "老余杭仓前配送员");
        jodIdMap.put("3d878a0412c7420233d829S7Elc~", "滨江配送员");
        jodIdMap.put("7aaa6b08a7e2750c33d_2NW-GFc~", "西湖区配送员");
        jodIdMap.put("3a0483cf5b247b2f33d_2NW9Elc~", "下城区配送员");
        jodIdMap.put("1766d97703b081a033Zy09-7ElI~", "西湖区配送员");
        jodIdMap.put("a9d045209b12593e33Z-2N27FFU~", "余杭星光街配送员");
        jodIdMap.put("38e66529aa177fa733Z-2N25GFI~", "三墩配送员");
        jodIdMap.put("ee941e1bfffa867b33Z43dS4Elc~", "杭州丁桥配送员");
        jodIdMap.put("c9ecff86de5679f333Z70ti4E1c~", "西湖区配送员");
        jodIdMap.put("ca106ccd9b9c333933Z70tm1F1o~", "老余杭配送员");
        jodIdMap.put("8fccd28320d48a8133V-39S_E1Q~", "上城区急缺1w+配送员");
        jodIdMap.put("389bc1e8c117d75633V43tS7FVo~", "城站配送员");
        jodIdMap.put("fa1a9a49071ef5bc33V739m9E1I~", "滨江配送员");
        jodIdMap.put("8fd08bb039b2e58333V63ty8GVA~", "配送员");
        jodIdMap.put("ec7539172fa677fd33R42dy6GVE~", "下城区配送员");
        jodIdMap.put("0945319a3278a2a933R42dy8GFU~", "拱墅区配送员");
        jodIdMap.put("72c2ff3dce72a26d33R63966F1Y~", "西湖急缺1w+配送员");
        jodIdMap.put("93685e3819119ccb0HJ_09W0F1Q~", "临平急缺1w+配送员");
        jodIdMap.put("d628c7e412abf9610HF53969EFs~", "九堡急缺1w+配送员");
        jodIdMap.put("d04f1faa549743870HF43921FlA~", "叮咚配送员");
        jodIdMap.put("f524835a6749c8b80HF4392-FVU~", "叮咚配送员");
        jodIdMap.put("15e3d712d41f598b0HF709S9EFI~", "富阳急缺万元配送员");
        jodIdMap.put("7df98aa1a2eaa0650HF709W4EFQ~", "配送员");
        jodIdMap.put("5d38a1dfe0817a200HBz3920EVY~", "配送员");
        jodIdMap.put("949c3af893ff8db70HBz3929EFI~", "配送员");
        jodIdMap.put("8bbda9f35895f78f0HBz2NS7EVs~", "配送员");
        jodIdMap.put("fd6e64f66dd426240HBz2NW0EVM~", "配送员");
        jodIdMap.put("b3e10db17f8c0e9e0HBy3d25Flo~", "配送员");
        jodIdMap.put("8de0e5f20c2593120HVz0t6_F1Q~", "配送员");
        jodIdMap.put("de3f5d53026184f60HV42tu8ElE~", "三堡急缺1w+配送员");
        jodIdMap.put("17595e04d90bc0680HRy3di8EVQ~", "三堡急缺1w配送员");
        jodIdMap.put("969ff25934b7206a0HR_29y8E1s~", "钱塘雅苑急聘1w+配送员");
        jodIdMap.put("989779b5cfcb6a290HR-0tW5GVU~", "城站急招1w+配送员");
        jodIdMap.put("8661d3d091ef7b0c0HR63t28EVA~", "急招上城区1w+配送员");
        jodIdMap.put("604784f9bcfa96770X1y2Nu5EVM~", "西湖区急聘1w+配送员");
        jodIdMap.put("61042f78bc9ebca40X193Nq8EFA~", "滨江急聘1w+配送员");
    }

    private static void endLog() {
        System.out.println(jobCountMap);
        System.out.println(String.format(endMsg, totalFilterCount, totalFilterCountOfChat, totalFilterCountOfJob, totalFilterCountOfAge));
    }

    private static void oneLog(Integer newFriend) {
        System.out.println(String.format(logMsg, no++,
                (System.currentTimeMillis() - time) / 1000L,
                totalFilterCountOfChat - totalFilterCountOfChatTemp,
                totalFilterCountOfJob - totalFilterCountOfJobTemp,
                totalFilterCountOfAge - totalFilterCountOfAgeTemp,
                newFriend));

        totalFilterCountOfJobTemp = totalFilterCountOfJob;
        totalFilterCountOfChatTemp = totalFilterCountOfChat;
        totalFilterCountOfAgeTemp = totalFilterCountOfAge;
        time = System.currentTimeMillis();
    }

    public static void main(String[] args) throws Exception {
        try {
//            System.out.println(getAlreadyChat());
            start();
            endLog();
        } catch (Exception e) {
            endLog();
            throw e;
        }
    }

    public static void start() throws Exception {
        for (String jobId : jodIdMap.keySet()) {
            try {
                for (int i = 0; i < 10; i++) {
                    if (end == 1) {
                        return;
                    }
                    Map<String, String> paramMap = getParamsOfList(jobId, 1);
                    JSONObject listResponse = get(URL_LIST, paramMap, getHeaderMap());

                    JSONArray geekList;
                    try {
                        assert Objects.nonNull(listResponse);
                        Integer code = listResponse.getInteger("code");
                        assert Objects.nonNull(code);
                        assert code == 0;
                        JSONObject zpData = listResponse.getJSONObject("zpData");
                        assert Objects.nonNull(zpData);
                        geekList = zpData.getJSONArray("geekList");
                        assert Objects.nonNull(geekList);
                    } catch (Exception e) {
                        System.out.println("[boss]列表失败. listResponse: ");
                        System.out.println(listResponse);
                        System.out.println("\n");
                        throw e;
                    }

                    if (Objects.isNull(geekList)) {
                        System.out.println(listResponse);
                        if (++failCount > 2) {
//                            throw new Exception("错误5次");
                            Thread.sleep(sleepTime);
                            break;
                        }
                        Thread.sleep(sleepTime);
                        continue;
                    }

                    Iterator<Object> iterator = geekList.iterator();
                    while (iterator.hasNext()) {
                        Object s = iterator.next();
                        if (Objects.isNull(s)) {
                            continue;
                        }
                        JSONObject geekJson = (JSONObject) s;
                        String encryptGeekId = geekJson.getString("encryptGeekId");
                        String expectId = JSONPath.eval(geekJson, "$.geekCard.expectId") + "";
                        String lid = (String) JSONPath.eval(geekJson, "$.geekCard.lid");
                        String securityId = (String) JSONPath.eval(geekJson, "$.geekCard.securityId");
                        String expectPositionName = (String) JSONPath.eval(geekJson, "$.geekCard.expectPositionName");
                        String ageDesc = (String) JSONPath.eval(geekJson, "$.geekCard.ageDesc");
                        Integer haveChatted = geekJson.getInteger("haveChatted");
                        Integer isFriend = geekJson.getInteger("isFriend");
                        Boolean friendGeek = geekJson.getBoolean("friendGeek");

                        jobAdd(expectPositionName);

                        // 条件
                        if (haveChatted == 1 || isFriend == 1 || Boolean.TRUE.equals(friendGeek)) {
                            totalFilterCount++;
                            totalFilterCountOfChat++;
                            continue;
                        }

                        if (!expectSet.contains(expectPositionName)) {
                            totalFilterCount++;
                            totalFilterCountOfJob++;
                            continue;
                        }

                        int age = Strings.isNullOrEmpty(ageDesc) ? 0 : Integer.parseInt(ageDesc.replace("岁", ""));
                        if (age < 18 || age > 44) {
                            totalFilterCount++;
                            totalFilterCountOfAge++;
                            continue;
                        }

                        Map<String, String> paramsOfHello = getParamsOfHello(jobId, encryptGeekId, expectId, lid, securityId);
                        try {
                            JSONObject helloResponse = post(URL_HELLO + System.currentTimeMillis(), paramsOfHello, getHeaderMap());
                            Integer codeOfHello = helloResponse.getInteger("code");
                            assert Objects.nonNull(codeOfHello);
                            if (codeOfHello != 0) {
                                System.out.println("[boss]招呼失败. helloResponse:");
                                System.out.println(helloResponse);
                                System.out.println("\n");
                                if (++helloFailCount > 5) {
                                    throw new Exception("招呼失败");
                                }
                            } else {
                                Integer newFriend = (Integer) JSONPath.eval(helloResponse, "$.zpData.newfriend");
                                if (newFriend != null && newFriend == 1) {
                                    oneLog(newFriend);
                                } else {
                                    totalFilterCount++;
                                    totalFilterCountOfChat++;
                                }
                            }
                        } catch (Exception e) {
                            System.out.println("[boss]招呼错误");
                            System.out.println(e);
                            System.out.println("\n");
                            if (++helloFailCount > 5) {
                                throw new Exception("招呼错误");
                            }
                        }
                        Thread.sleep(sleepTime);
                    }
                }
            } catch (Exception e) {
                System.out.println("job: " + jodIdMap.get(jobId));
                throw e;
            }
        }
    }

    static Map<String, String> getParamsOfList(String jonId, int page) {
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("jobid", jonId);
        paramMap.put("status", "0");
        paramMap.put("refresh", "" + (System.currentTimeMillis() - 1000L));
        paramMap.put("source", "0");
        paramMap.put("age", "18,44");
        paramMap.put("gender", "-1");
        paramMap.put("exchangeResumeWithColleague", "0");
        paramMap.put("recentNotView", "-1");
        paramMap.put("activation", active);
        paramMap.put("experience", "0");
        paramMap.put("degree", "0");
        paramMap.put("salary", "0");
        paramMap.put("intention", "-1");
        paramMap.put("cityCode", "");
        paramMap.put("districtCode", "");
        paramMap.put("businessId", "");
        paramMap.put("page", "" + page);
        paramMap.put("jobId", jonId);
        paramMap.put("_", "" + System.currentTimeMillis());
        return paramMap;
    }

    static Map<String, String> getParamsOfHello(String jid, String encryptGeekId, String expectId, String lid, String securityId) {
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("gid", encryptGeekId);
        paramMap.put("jid", jid);
        paramMap.put("expectId", expectId);
        paramMap.put("lid", lid);
        paramMap.put("securityId", securityId);
        paramMap.put("suid", "");
        paramMap.put("from", "");
        return paramMap;
    }

    static Map<String, String> getHeaderMap() {
        Map<String, String> headerMap = Maps.newHashMap();
        headerMap.put("authority", "www.zhipin.com");
        headerMap.put("accept", "application/json, text/plain, */*");
        headerMap.put("x-requested-with", "XMLHttpRequest");
        headerMap.put("x-anti-request-token", "d41d8cd98f00b204e9800998ecf8427e");
        headerMap.put("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36");
        headerMap.put("token", "SG9XgViy65vcVFq");
        headerMap.put("zp_token", "V1QtMkFOb02FdgXdNrzhsYLCi25TrVwA~~");
        headerMap.put("traceid", "9996E13B-336C-4843-A4F2-9676EDCD9A7D");
        headerMap.put("sec-fetch-site", "same-origin");
        headerMap.put("sec-fetch-mode", "cors");
        headerMap.put("sec-fetch-dest", "empty");
        headerMap.put("sec-ch-ua", "\"Chromium\";v=\"88\", \"Google Chrome\";v=\"88\", \";Not A Brand\";v=\"99\"");
        headerMap.put("sec-ch-ua-mobile", "");
        headerMap.put("referer", "https://www.zhipin.com/vue/index/");
        headerMap.put("accept-language", "zh-CN,zh;q=0.9");
        headerMap.put("cookie", "lastCity=101210100; _bl_uid=pjk6Oobsydddb5meRmd08Ceh8jUI; __g=-; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1620567567,1621090310,1622297875; wt2=DDBzYyZpxik3aBNi3aouq4-XOeoEGcSUSlBOl2g9sTD_Px6_cgsGeVdnVFNHG6IDqV-OTpt62ueKlM6P85rVHMQ~~; zp_token=V1QtMkFOb02FdgXdNrzR8RIS-07z_WwA%7E%7E; __c=1622297875; __l=l=%2Fwww.zhipin.com%2Fweb%2Fboss%2Findex&r=&g=&s=3&friend_source=0&s=3&friend_source=0; __a=24493547.1618147484.1621090310.1622297875.126.11.4.126; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1622297903; __f=e20a9d3074e677eb39e549cdd6fb192d");
        return headerMap;
    }

    static JSONObject get(String url, Map<String, String> paramMap, Map<String, String> headerMap) throws Exception {
        URIBuilder uriBuilder = new URIBuilder(url);

        if (CollectionUtil.isNotEmpty(paramMap)) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                uriBuilder.addParameter(entry.getKey(), entry.getValue());
            }
        }

        HttpGet httpGet = new HttpGet(uriBuilder.build());
        if (CollectionUtil.isNotEmpty(headerMap)) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                httpGet.addHeader(entry.getKey(), entry.getValue());
            }
        }

        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                // 使用Apache提供的工具类进行转换成字符串
                String entityStr = EntityUtils.toString(entity, "UTF-8");

                return JSONObject.parseObject(entityStr);
            }
        } finally {
            // 释放资源
            if (response != null) {
                response.close();
            }
        }
        return null;
    }

    static JSONObject post(String url, Map<String, String> paramMap, Map<String, String> headerMap) throws Exception {
        URIBuilder uriBuilder = new URIBuilder(url);

        if (CollectionUtil.isNotEmpty(paramMap)) {
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                uriBuilder.addParameter(entry.getKey(), entry.getValue());
            }
        }

        HttpPost httpPost = new HttpPost(uriBuilder.build());
        if (CollectionUtil.isNotEmpty(headerMap)) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }
        }

        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                // 使用Apache提供的工具类进行转换成字符串
                String entityStr = EntityUtils.toString(entity, "UTF-8");

                return JSONObject.parseObject(entityStr);
            }
        } finally {
            // 释放资源
            if (response != null) {
                response.close();
            }
        }
        return null;
    }

    private static void jobAdd(String job) {
        if (!jobCountMap.containsKey(job)) {
            jobCountMap.put(job, 0);
        }
        jobCountMap.put(job, jobCountMap.get(job) + 1);
    }

    private static int getAlreadyChat() throws Exception {
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("from", "");
        JSONObject response = get(URL_LIST, paramMap, getHeaderMap());
        Integer usedCount = (Integer) JSONPath.eval(response, "$.zpData.currentPrivilegeUsed[1].usedCount");
        return  usedCount == null ? 0 : usedCount;
    }
}
